import random

__ver__ = "0.1"

class Player:
    def __init__(self, name, money, id):
        self.id = id
        self.money = money
        self.name = name
        self.allin = False
        
    def getMoney(self):
        return self.money
    
    def setMoney(self, money):
        self.money = money
        
    def getId(self):
        return self.id
    
    def setHoleCards(self, card1, card2):
        self.cards = [card1, card2]
        
    def setFaceCard(self, card):
        self.faceCard = card
        
    def getHoleCards(self):
        return self.cards
    
    def getFaceCard(self):
        return self.faceCard
    
    def getName(self):
        return self.name
    
    def setAllin(self):
        self.allin = True
        
    def getAllin(self):
        return self.allin
    
    def newRound(self):
        self.cards = []

class Game:
    def __init__(self, limit = [5, 10]):
        self.cardValue = [2, 3, 4, 5, 6, 7, 8, 9, 10, 'J', 'Q', 'K', 'A']
        self.cardSign = ['h', 'd', 's', 'c'] # hearts, diamonds, spade, clubs
        self.deck = []
        self.flop = []
        self.turn = []
        self.river = []        
        self.limit = limit    # limit fuer blinds limit[0] - smallBlind; limit[1] - bigBlind
        self.round = 0 # 0 - preflop; 1 - flop; 2 - turn; 3 - river
        self.pot = 0          # am Anfang is nix drin  
        self.buildDeck()

    def buildDeck(self):
        for x in self.cardValue: # baut das Deck sortiert zusammen
            for y in self.cardSign:
                self.deck.append((x, y))
                
    def shuffleDeck(self):
        random.shuffle(self.deck)
        
    def showDeck(self):
        for x in self.deck:
            print "Karte %d: %s%s" % (self.deck.index((x[0], x[1])) + 1, x[0], x[1])
            
    def dealFaceCard(self, player):
        card = self.deck[0]
        player.setFaceCard(card)
        self.deck.remove(card)
        
    def dealHoleCards(self, player):
        """Deals HoleCards of a player-object."""
        card1 = self.deck[0]
        card2 = self.deck[1]
        player.setHoleCards(card1, card2)
        self.deck.remove(card1)
        self.deck.remove(card2)
        
    def showHoleCards(self, player):
        """Shows HoleCards of a player-object."""
        cards = player.getHoleCards()
        card1 = cards[0]
        card2 = cards[1]
        
        print "Cards for %s: %s%s %s%s" % (player.getName(), card1[0], card1[1], card2[0], card2[1])
            
    def dealFlop(self):
        for i in range(3):
            self.flop.append(self.deck[i])
            self.deck.remove(self.deck[i])
            
    def showFlop(self):
        card1 = self.flop[0]
        card2 = self.flop[1]
        card3 = self.flop[2]
        print "Dealing Flop: %s%s, %s%s, %s%s" % (card1[0], card1[1], card2[0], card2[1], card3[0], card3[1])
        
    def dealTurn(self):
        self.turn.append(self.deck[0])
        self.deck.remove(self.deck[0])
        
    def showTurn(self):
        card = self.turn[0]
        print "Dealing Turn: %s%s" % (card[0], card[1])
        
    def dealRiver(self): 
        self.river.append(self.deck[0])
        self.deck.remove(self.deck[0])
        
    def showRiver(self):
        card = self.river[0]
        print "Dealing River: %s%s" % (card[0], card[1])
        
    def getPot(self): # hoehoe
        return self.pot 
        
    def restart(self):
        """Restarts the Game (e.g. for a new round)"""
        self.deck = []
        self.flop = []
        self.turn = []
        self.river = []
        self.round = 0        # 0 - preflop; 1 - flop; 2 - turn; 3 - river
        self.pot = 0          # am Anfang is nix drin  
        self.buildDeck()
        self.startGame(players)
        
    def bet(self, player):
        """Player bets during a betting round
        
        params: Player(), bettingRound = (0, 1, 2, 3)"""
        smallBet = self.limit[1]     # Small Bet = Big Blind
        bigBet = self.limit[1] * 2   # Big Bet = Big Blind * 2
        
        if self.round <= 1:
            if player.getMoney() > smallBet:
                newMoney = player.getMoney() - smallBet
                player.setMoney(newMoney)
                self.pot += smallBet
            else:
                moneyLeft = player.getMoney()
                player.setMoney(0)
                self.pot += moneyLeft
        else:
            if player.getMoney() > bigBet:
                newMoney = player.getMoney() - bigBet
                player.setMoney(newMoney)
                self.pot += bigBet
                player.setAllin()
            else:
                moneyLeft = player.getMoney()
                player.setMoney(0)
                self.pot += moneyLeft
                player.setAllin()   
            
    def bettingRound(self, players, dealer):
        bets = 0
        smallBlind = (dealer+1) - len(players)            # index of smallBlind
        firstToAct = (smallBlind + 2) - len(players)      # index of guy after bigBlind
        
        for pl in range(firstToAct, (smallBlind + 2)): # kompliziert aber funzt
            if bets <= 3:
                answer = raw_input("Player %s: (b)et, (c)all/check or (f)old > " % players[pl].getName())
                if answer == 'b':
                    self.bet(players[pl])
                    bets += 1
                elif answer == 'c':
                    pass
                elif answer == 'f':
                    pass
            else:
                answer = raw_input("Player %s: (c)all or (f)old > " % players[pl].getName())
                if answer == 'c':
                    pass
                elif answer == 'f':
                    pass
        
        self.round += 1
            
    def whoIsDealer(self, players):
        """Decides who start the first round
    
        return int players[int]"""

        #TODO Stimmt noch nicht ganz erstes Ace im Spiel muesste Dealer sein
        #     nicht das letzte im Spiel :P
        dealer = 0
        for player in range(len(players)):
            if players[player].getFaceCard()[0] == 'A':
                dealer = player
            elif players[player].getFaceCard() > players[dealer].getFaceCard():
                dealer = player
            
        return dealer
    
    def startGame(self, players):
        print ""
        print "Start Game..."
        print ""
        
        self.shuffleDeck()
        
        # Decide who starts1
        for pl in range(playersAmount):
            self.dealFaceCard(players[pl])
        
        for pl in range(playersAmount):
            print "%s has %s%s as FaceCard" % (players[pl].getName(), players[pl].getFaceCard()[0], players[pl].getFaceCard()[1])
            
        self.dealer = self.whoIsDealer(players)
        self.mainLoop(players, self.dealer)
        
        
    def mainLoop(self, players, dealer):
        while True: # GameLoop
            self.shuffleDeck()
            smallBlind = (dealer+1) - len(players)            # index of smallBlind
            firstToAct = (smallBlind + 2) - len(players)      # index of guy after bigBlind

            print "Dealer for this round is %s\n" % players[dealer].getName()

            # Dealing HoleCards
            for pl in range(smallBlind, (dealer+1)): # kompliziert, aber funzt
                self.dealHoleCards(players[pl])
                self.showHoleCards(players[pl])
            
            # First Betting Round
            self.bettingRound(players, self.dealer)
        
            # Dealing Flop
        
            # Second Betting Round
        
            # Dealing Turn
        
            # Third Betting Round

            # Dealing River
        
            # Fourth Betting Round

            # Who is the winner?

            # Ask if restart or break

            answer = str(raw_input("Do you wish to exit? (y/n): "))
            if answer == "y":
                print "End Game..."
                break
            else:
                if self.dealer == len(players) - 1: 
                    self.dealer = 0
                else:
                    self.dealer += 1
                self.restart()
        
if __name__ == '__main__':
    print "#######################"
    print "#     PyPoker %s     #" % __ver__
    print "#######################"
    print ""
    playersAmount = int(raw_input("Please enter amount of players: "))
        
    players = []
        
    for x in range(playersAmount):
        players.append(Player(raw_input("Please enter name: "), int(raw_input("Please enter money: ")), x))
        
    limit = [int(raw_input("Small Blind: ")), int(raw_input("Big Blind: "))]
    
    game = Game(limit)
    game.startGame(players)
